import json
import re
import time

import requests
import zipfile
import os
import platform
from tqdm import tqdm
from config_logger import config, log, errorTimes
from nofity import notify_server
from send_message import Send


class VideoDownloader:
    TEST_IP = config.get('ENV', "testIp")
    PROD_IP = config.get('ENV', "prodIp")
    errorTimes[f"{TEST_IP}_theNumberOfTimeouts"] = 0
    errorTimes[f"{PROD_IP}_theNumberOfTimeouts"] = 0
    def __init__(self, extract_to):
        self.extract_to = extract_to

    def get_video_url(self):
        ip = self.PROD_IP
        try:
            hostname = platform.node()  # 获取服务器名称
            params = {"hostName": hostname}
            header = {"log-less": "1"}
            response = requests.get(ip + "/api/ai/video/jianying-task", params=params, headers=header, timeout=5)
            response.raise_for_status()
            data = response.json().get('data')
            log.info(f"生产环境:{response.json()}")
            errorTimes[f"{ip}_theNumberOfTimeouts"] = 0
            if not data:  # 如果生产没有任务
                ip = self.TEST_IP
                response = requests.get(ip + "/api/ai/video/jianying-task", params=params, headers=header, timeout=5)
                response.raise_for_status()
                data = response.json().get('data')
                log.info(f"测试环境:{response.json()}")
                errorTimes["RequestExceptionTimes"] = 0
                errorTimes[f"{ip}_theNumberOfTimeouts"] = 0
                if not data:
                    return None, None
            errorTimes["RequestExceptionTimes"] = 0
            return data, ip
        except requests.Timeout as e:
            # 打印超时日志
            errorTimes[f"{ip}_theNumberOfTimeouts"] = errorTimes[f"{ip}_theNumberOfTimeouts"] + 1
            if errorTimes[f"{ip}_theNumberOfTimeouts"] == 3:
                log.error(f"{ip}拉取任务连续三次请求超时{e}")
                errorTimes[f"{ip}_theNumberOfTimeouts"] = 0
            return None, None
        except (requests.RequestException, json.JSONDecodeError) as e:
            time.sleep(30)  # 服务器重启等待时间
            errorTimes["RequestExceptionTimes"] = errorTimes["RequestExceptionTimes"] + 1
            if errorTimes["RequestExceptionTimes"] == 3:
                log.error(f"{ip}拉取任务请求或解码失败: {e}")
                Send.qywxmsg(f"{ip}拉取任务请求失败: {e}")
                errorTimes["RequestExceptionTimes"] = 0
            return None, None
        except BaseException as e:
            log.error(f"{ip}拉取任务未知错误:{e}")
            return None, None

    def download_and_extract_zip(self):
        video_data, ip = self.get_video_url()
        if not video_data:
            return None, None, None, None

        task_id = video_data.get('taskId')  # 用来上报任务
        jianying_zip_url = video_data.get('jianYingZipUrl')  # 视频url
        organizeId = video_data.get('organizeId') if video_data.get('organizeId') else 0 # 企业id

        if not task_id or not jianying_zip_url:
            log.info("无效的任务ID或ZIP URL")
            return None, None, None, None

        # 使用正则表达式匹配URL中的数字序列
        match = re.search(r'(\d+)', jianying_zip_url)
        if match:
            video_id = match.group(0)
        else:
            log.error(f"No numbers found in the URL:{jianying_zip_url}.")
            return None, None, None, None

        os.makedirs(self.extract_to, exist_ok=True)
        start_time = time.time()  # 记录开始时间
        try:
            with requests.get(jianying_zip_url, stream=True) as r:
                r.raise_for_status()
                total_size = int(r.headers.get('content-length', 0))
                zip_filename = os.path.join(self.extract_to, f"{task_id}_jy.zip")
                with open(zip_filename, 'wb') as zip_file:
                    progress_bar = tqdm(total=total_size, unit='iB', unit_scale=True, desc=f"Downloading {task_id}")
                    for chunk in r.iter_content(chunk_size=8192):
                        if chunk:  # 过滤掉保持连接的chunk
                            progress_bar.update(len(chunk))
                            zip_file.write(chunk)
                    progress_bar.close()

            with zipfile.ZipFile(zip_filename, 'r') as zip_ref:
                zip_ref.extractall(self.extract_to)

            os.remove(zip_filename)
            end_time = time.time()    # 记录结束时间
            execution_time = end_time - start_time  # 计算执行时间
            log.info(f"文件已成功下载并解压到 {self.extract_to},耗时：{execution_time}秒")
            return task_id, ip, video_id,organizeId
        except (requests.RequestException, zipfile.BadZipFile, OSError) as e:
            log.error(f"文件下载或解压失败: {e}")
            notify_server(ip, task_id, -2, errorInfo="文件下载或解压失败")
            Send.qywxmsg(f"{ip},task_id:{task_id}生成失败,失败原因：文件下载或解压失败,下载链接:{jianying_zip_url}")
            return None, None, None, None


if __name__ == '__main__':
    downloader = VideoDownloader(config.get('JY_PATH', 'Drafts_path'))

    downloader.get_video_url()

